import { computed } from 'vue';
import { isDate } from '@/utils/is';
import { dayjs } from "element-plus";

/**
 * 帮助类
 */
export const util = {
    /**
     * 格式化时间
     * @param time
     */
    getTime: (time: number) => {
        let date = new Date(time);
        let y = date.getFullYear();
        let M = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
        let d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
        let h = date.getHours() < 10 ? '0' + date.getHours() + ':' : date.getHours() + ':';
        let m = date.getMinutes() < 10 ? '0' + date.getMinutes() + ':' : date.getMinutes() + ':';
        let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
        return y + '-' + M + '-' + d + ' ' + h + m + s;
    },
    /**
     * 格式化时间
     * @param time
     */
    timeFormatter: (date?: Date) => {
        if (date) {
            let y = date.getFullYear();
            if (y === 1900 || y === 2001) {
                return '-';
            }
            let M = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
            let d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
            let h = date.getHours() < 10 ? '0' + date.getHours() + ':' : date.getHours() + ':';
            let m = date.getMinutes() < 10 ? '0' + date.getMinutes() + ':' : date.getMinutes() + ':';
            let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds();
            return y + '-' + M + '-' + d + ' ' + h + m + s;
        }
        return '';
    },
    /**
     * 格式化时间 yyyy-MM-DD HH:mm:ss
     * @param date
     */
    getDateText: (date: any | undefined) => {
        if (!date) {
            return '-';
        }
        if (isDate(date)) {
            if (date.getFullYear() < 2000) {
                return '-';
            }
            return dayjs(date).format('yyyy-MM-DD HH:mm:ss');
        }
        return date;
    },
};

/**
 * 资源读取地址拼接
 * @param rid
 */
export const createZYImageUrl = (rid: string) => {
    if (rid.startsWith('http')) {
        return `/api/Resources-Resources/get?fileId=${encodeURIComponent(rid)}`;
    }
    if (rid.startsWith('api') || rid.startsWith('/api')) {
        return rid;
    }
    return `/api/Resources-Resources/get?fileId=${encodeURIComponent(rid)}`;
};

/**
 * 图片预览资源读取地址拼接
 * @param rid 资源ID
 * @param size 大小(100*100)
 */
export const createZYPreviewImageUrl = (rid: string, size: string) => {
    if (rid.startsWith('http')) {
        return `/api/Resources-Resources/GetPreviewImage?fileId=${encodeURIComponent(rid)}&size=${size}`;
    }
    if (rid.startsWith('api') || rid.startsWith('/api')) {
        return rid;
    }
    return `/api/Resources-Resources/GetPreviewImage?fileId=${encodeURIComponent(rid)}&size=${size}`;
};

/**
 * 视频预览资源读取地址拼接
 * @param rid 资源ID
 * @param size 大小(100*100)
 */
export const createZYPreviewVideoCoverUrl = (rid: string, size: string) => {
    if (rid.startsWith('http')) {
        return rid;
    }
    if (rid.startsWith('api') || rid.startsWith('/api')) {
        return rid;
    }
    return `/api/Resources-Resources/GetVideoCover?fileId=${rid}&size=${size}`;
};

/**
 * 资源读取地址拼接
 * @param rids
 */
export const createZYImageUrls = (rids: string[]) => {
    let urls: string[] = [];
    rids.forEach((item) => {
        let url = createZYImageUrl(item);
        urls.push(url);
    });
    return urls;
};

/**
 * 获取配置页面固定的高度
 */
export const getConfigContentClientHeight = (offset?: number) => {
    return computed(() => getConfigContentClientHeightValue(offset));
};

/**
 * 获取配置页面固定的高度
 * @param offset
 */
export const getConfigContentClientHeightValue = (offset?: number) => {
    let offsetVal = 0;
    if (!offset) {
        offsetVal = 0;
    } else {
        offsetVal = offset;
    }
    return document.body.clientHeight - 80 - 70 - 50 - offsetVal;
};

/**
 * 深度复制对象
 * @param sourceData
 */
export function deepCopy<T extends unknown>(sourceData: T): T {
    if (Array.isArray(sourceData)) {
        return sourceData.map((item) => deepCopy(item)) as T;
    }
    const obj: T = {} as T;
    for (let key in sourceData) {
        if (isDate(sourceData[key])) {
            obj[key] = sourceData[key];
        } else if (typeof sourceData[key] === 'object' && sourceData[key] !== null) {
            obj[key] = deepCopy(sourceData[key]);
        } else {
            obj[key] = sourceData[key];
        }
    }
    return obj;
}

/**
 * 获取元素距离视图窗口顶部的距离
 * @param elem
 */
export function getElementTop(elem: HTMLElement) {
    let elemTop = elem.offsetTop; //获得elem元素距相对定位的父元素的top
    elem = elem.offsetParent as HTMLElement; //将elem换成起相对定位的父元素
    while (elem != null) {
        //只要还有相对定位的父元素
        //获得父元素 距他父元素的top值,累加到结果中
        elemTop += elem.offsetTop;
        //再次将elem换成他相对定位的父元素上;
        elem = elem.offsetParent as HTMLElement;
    }
    return elemTop;
}

/**
 * 标记名称使其与其他字段相区别
 * @param name 需要包裹的字段
 * @returns
 */
export const coverName = (name?: string | undefined) => {
    return `「${name}」`;
};

/**
 * 防抖函数
 * @param func 回调
 * @param delay 时间 默认200
 * @returns 
 */
export const debounce = <T extends (...args: T[]) => void> (func: T, delay = 200) => {
    let timeout: number | null = null;
    const _this = this;
    return function (this: any, ...args: Parameters<T>) {
        timeout && clearTimeout(timeout);
        timeout = setTimeout(() => {
            func.apply(_this, args);
        }, delay);
    };
};

/**
 * 计算百分比
 * @param a 
 * @param b 
 * @returns 
 */
export const getPercentage = (a: number, b: number): number => {
    if (a === 0 && b === 0) return a;
    return Number((((a - b) / a) * 100).toFixed(0));
};

/**
 * 获取两个数的百分比
 * @param a 总数
 * @param b 小数
 */
export const getPercentageV2 = (a?: number, b?: number): number => {
    if (!a || !b || (a === 0) || (b === 0)) return 0;
    return Number(((b / a) * 100).toFixed(2));
};

/**
 * 获取数字整数部分
 * @param a 数值
 */
export const getNumberInteger = (a: number): number => {
    let arr = a.toString().split('.');
    if (arr.length >= 1) {
        return Number(arr[0]);
    }
    return a;
};

/**
 * 获取数字小数部分
 * @param a 数值
 */
export const getNumberDecimal = (a?: number | string): number => {
    let arr = a ? a.toString().split('.') : '';
    if (arr.length >= 2) {
        if (arr[1].length > 2) {
            return Number(arr[1].substring(0, 2));
        }
        return Number(arr[1]);
    }
    return 0;
};

/**
 * 获取数字小数部分转换成格式.01
 * @param a 数值
 */
export const getNumberDecimalText = (a?: number | string): string => {
    let arr = a ? a.toString().split('.') : '';
    if (arr.length >= 2) {
        return '.' + arr[1];
    }
    return '';
};

/**
 * 格式化余额
 * @param num 
 * @returns 
 */
function moneyFormat(num: string | number) {
    return String(num).replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
}

/**
 * 获取数值整数部分并且转换金额的字符串 2,000,000
 * @param a
 */
export const getNumberIntegerMoeny = (a?: string | number) => {
    const num = getNumberInteger(Number(a)).toString();
    const len = num.length;
    return len <= 3 ? num : moneyFormat(num.substr(0, len - 3)) + ',' + num.substr(len - 3, 3);
};

/**
 * 获取数值整数部分并且转换金额的字符串 2,000,000 支持小数
 * @param a
 */
export const getNumberIntegerMoenyAndDecimal = (a: string | number) => {
    const num = getNumberInteger(Number(a)).toString();
    const len = num.length;
    const result = len <= 3 ? num : moneyFormat(num.substr(0, len - 3)) + ',' + num.substr(len - 3, 3);
    const dec = getNumberDecimal(a);
    if (dec > 0) {
        return result + '.' + dec;
    }
    return result;
};

/**
 * file 转Base64 DataURL
 * @param {File} file
 * @returns
 */
export const fileToBase64Async = (file: File) => {
    return new Promise<string>((resolve) => {
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (e) => {
            resolve(e.target?.result as string);
        };
    });
};

/**
 * 格式化base64 转换成后端可识别的原始数据
 * @param data
 */
export const formatBase64ToOriginal = (data: string) => {
    let res = /data:.+;base64,([\w\W]+)/.exec(data);
    console.log(res);
    if (!res) {
        return '';
    }
    if (res.length <= 0) {
        return '';
    }
    return res[1];
};

/**
 * 获取路由参数
 * @returns 
 */
export const getRouterParams = () => {
    return history.state.params ?? {};
};

/**
 * 获取环比
 * @param a 
 * @param b 
 * @returns 
 */
export const getMonthonmonthRatio = (a: number, b: number) => {
    if (a == 0 || b == 0) {
        return '0%';
    }
    return (((Math.round(b - a) / a) * 100.0).toFixed(2) + '%').replace('-', '');
};

/**
 * 获取环比升价符号
 * @param a 
 * @param b 
 * @returns 
 */
export const getMonthonmonthRatioSymbol = (a: number, b: number) => {
    if (a == 0 || b == 0) {
        return '';
    }
    return a < b ? '+' : '-';
};

/**
 * 如果数字大于万显示万
 * @param value
 * @param decimal
 * @param size
 */
export const transNumberToShort = (value: number, decimal = 2, size = ['', '万', '亿', '万亿']) => {
    const BASE = 10000;

    if (isNaN(value)) {
        throw new Error('The input parameter is not a number.');
    }
    if (decimal < 0) {
        throw new Error("The 'decimal' parameter should be a non-negative number.");
    }
    if (value < BASE) {
        return [value, size[0]];
    } else {
        const i = Math.floor(Math.log(value) / Math.log(BASE));
        return [`${(value / Math.pow(BASE, i)).toFixed(decimal)}`, size[i]];
    }
};
/**
 * 删除数组的某项数据
 * @param datas 数组
 * @param predicate 删除条件
 */
export const removeArrayItem = <T>(datas: Array<T>, predicate: (value: T, index: number, obj: T[]) => unknown) => {
    const index = datas.findIndex(predicate);
    if (index > 0) {
        datas.splice(index, 1);
    }
};

/**
 * 随机选择单个元素
 * @param items 数组
 */
export const randSelectItem = (items?: Array<string>) => {
    if (!items) {
        return '';
    }
    const randomIndex = Math.floor(Math.random() * items.length);
    return items[randomIndex];
};

// 替换字符串中的换行转成THML
export const replaceEnterToHtml = (str?: string) => {
    if (str == undefined) {
        return '';
    }
    return str.replace(/\n/g, '<br>');
};
